#include "GameManager.h"
#include "FlowController.h"
#include "SimpleAudioEngine.h"

#include "Character/Character.h"
#include "Map/GameMap.h"
#include "Levels/Level.h"
#include "Levels/LevelLoader.h"
#include "Levels/CatSpawnScript.h"
#include "Skills/BaseSkill.h"
#include "Skills/SkillsLoader.h"
#include "Skills/SkillEarthquake.h"

#include "Cats/BaseCat.h"
#include "Cats/CatsManager.h"
#include "Cats/CatSpriteLoader.h"

#include "Director/AIDirector.h"
#include "Director/PlayerPerformance.h"

#include "Modifier/GameModifier.h"

#include "Supporting/CCBlade.h"
#include "Supporting/Enums/EnumSkillType.h"
#include "Supporting/Enums/EnumScreenType.h"
#include "Supporting/PlayerData.h"
#include "Supporting/SoundLoader.h"

using namespace cocos2d;
using namespace CocosDenshion;

GameManager* GameManager::createLayer()
{
    // 'scene' is an autorelease object
    //CCScene *scene = CCScene::create();
    
    // 'layer' is an autorelease object
    GameManager *layer = GameManager::create();

    // add layer as a child to scene
    //scene->addChild(layer);

    // return the scene
    return layer;
}

GameManager::GameManager()
{
}

GameManager::~GameManager()
{
	SoundLoader::endSound(BACKGROUND_MUSIC);
	CocosDenshion::SimpleAudioEngine::sharedEngine()->stopAllEffects();

	GameMap::deleteInstance();
	myMap = NULL;

//	Character::deleteInstance();
//	myCharacter = NULL;

	CatsManager::deleteInstance();
	myCatsManager = NULL;

	delete myLevel;
	myLevel = NULL;

	delete myAIDirector;
	myAIDirector = NULL;

	delete myPlayerPerformance;
	myPlayerPerformance = NULL;

	if( myHealthUI )
	{
		myHealthUI->release();
		myHealthUI = NULL;
	}

	if( mySkillChargeUI )
	{
		mySkillChargeUI->release();
		mySkillChargeUI = NULL;
	}

	if( mySkills )
	{
		mySkills->release();
		mySkills = NULL;
	}
}

// on "init" you need to initialize your instance
bool GameManager::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !CCLayer::init() )
    {
        return false;
    }

    //Enable touch and accelerometer
    this->setTouchEnabled(true);
    this->setAccelerometerEnabled(true);

    //Setup game level data
    //loadGame();

    //Setup Update functions
    this->setKeypadEnabled(true); //enable for backkey button
    this->scheduleUpdate();

    // Background Music
    SoundLoader::playSound(BACKGROUND_MUSIC);

    return true;
}

/*
 * @function: loadGame
 * @brief: Load all the neccessary data for the game
 * @param myLevelLoader: reference to the level loader in flow controller
 * @param levelnumber: level number to load level
 * @param mySkillsLoader: reference to the skills loader in flow controller
 * @result: All required data loaded into memory
 */
void GameManager::loadGame()
{
	CCSize size = CCDirector::sharedDirector()->getWinSize();

	//================ Levels ==============================================
	LevelLoader* ll = new LevelLoader();
	//get the value from the saved data. will crash if retrieve from LevelLoader passed in from FlowController
	myLevel = ll->getLevel(1);//PlayerData::getSelectedLevel()); //Temp to demonstrate loading purpose
	delete ll;

	//================ MAP ====================
	myMap = GameMap::getInstance();
	myMap->init(CCString::create("Game/Background/[BG] City 1.png"), this);

	//================ Character =================
	Character::resetInstance();
	myCharacter = Character::getInstance();
	myCharacter->init("Game/Character/[Human][Engineer] (100).png", myMap);
	this->addChild(myCharacter,CHARACTER);

	//============= CatsManager ===============
	//myCats = new CCArray;
	myCatsManager = CatsManager::getInstance();
	myCatsManager->init(2, myMap, myCharacter, this);
	myCatsManager->setLevelSpawnScript(myLevel->getSpawnScript());
	CatSpriteLoader::preloadSpriteSheets();

	//============ UI ==================
	float UIscaleFactor = myMap->getScaleFactor();

	//HP lives
	myHealthUI = new CCArray;
	for( int i = 0 ; i < 3 ; i++ )
	{
		CCSprite *healthFullSprite = CCSprite::create("Game/UI/[UI] HP Full.png");
		healthFullSprite->setScale(UIscaleFactor);
		healthFullSprite->setPositionY(size.height/2+(290*UIscaleFactor));
		healthFullSprite->setPositionX((i * 60 + 35) * UIscaleFactor);

		this->addChild(healthFullSprite,HEALTHSPRITE);
		myHealthUI->addObject(healthFullSprite);
	}

	//Progression Bar at top
	CCSprite * progressionBarSprite = CCSprite::create("Game/UI/[UI] Progress Bar - Base.png");
	progressionBarSprite->setScale(UIscaleFactor);
	progressionBarSprite->setPosition(ccp(size.width/2,size.height/2+(290*UIscaleFactor)));
	this->addChild(progressionBarSprite,PROGRESSIONSPRITE);

	CCSprite * progressFlagSprite = CCSprite::create("Game/UI/[UI] Progress Bar - Flag.png");
	progressFlagSprite->setScale(UIscaleFactor);
	progressFlagSprite->setPosition(ccp(size.width/2 + progressionBarSprite->getContentSize().width/2*UIscaleFactor,size.height/2+(290*UIscaleFactor)));
	this->addChild(progressFlagSprite,PROGRESSIONFLAGSPRITE);

	CCSprite * progressionSprite = CCSprite::create("Game/UI/[UI] Progress Bar - Face.png");
	progressionSprite->setScale(UIscaleFactor);
	progressionSprite->setPosition(ccp(size.width/2-200*UIscaleFactor,size.height/2+(290*UIscaleFactor)));
	progressionSprite->setTag(tagoffset+PROGRESSIONINDICATORSPRITE);
	this->addChild(progressionSprite,PROGRESSIONINDICATORSPRITE);
	progressionSprite->runAction(CCSequence::createWithTwoActions(
			CCMoveBy::create(myLevel->getLevelDuration(),ccp(400*UIscaleFactor,0)),
			CCCallFunc::create(this,callfunc_selector(GameManager::winGame))));

	//Skill bar
	CCSprite * skillbarSprite = CCSprite::create("Game/UI/[UI] Skill Bar - Base.png");
	skillbarSprite->setScale(UIscaleFactor);
	skillbarSprite->setPosition(ccp(size.width-(320*UIscaleFactor),62*UIscaleFactor));
	//skillbarSprite->setTag(950);
	this->addChild(skillbarSprite,SKILLBARSPRITE);

	//Skill bar - charge bar
	chargePoints = 0;
	mySkillChargeUI = new CCArray;

	//Pause button
	isPaused = false;
	CCSprite * pauseButtonSprite = CCSprite::create("Game/UI/[Button] Pause - Normal.png");
	CCSprite * pauseButtonSpritePressed = CCSprite::create("Game/UI/[Button] Pause - Pressed.png");
	CCMenuItemSprite* pauseButton = CCMenuItemSprite::create(pauseButtonSprite,pauseButtonSpritePressed,this,menu_selector(GameManager::pauseButtonPressed));
	pauseButton->setScale(UIscaleFactor);
	pauseButton->setPosition(ccp(size.width - (45*UIscaleFactor),size.height/2+(280*UIscaleFactor)));
    CCMenu* gamemenu = CCMenu::create(pauseButton, NULL);
    gamemenu->setPosition(0,0);
	this->addChild(gamemenu,PAUSEBUTTON);

	//======================== SKILL ===============================
	//mySkillsLoader = new SkillsLoader();
	//Retrieve the user selected skills from saved data
	//will crash when retrieve from SKillsLoader passed in from FlowController
	int slots[3];
	slots[0] = PlayerData::getSkillNumber(1);
	slots[1] = PlayerData::getSkillNumber(2);
	slots[2] = PlayerData::getSkillNumber(3);

	//Load the skills
	SkillsLoader* sl = new SkillsLoader();
	mySkills = sl->getSkill(slots[0],slots[1],slots[2]);
	delete sl;

	for( int i = 0 ; i < mySkills->count() ; i++ )
	{
		BaseSkill* pSkill = dynamic_cast<BaseSkill*>(mySkills->objectAtIndex(i));
		//pSkill->loadSkill();
		pSkill->setScale(0.9*UIscaleFactor);

		if( i == 0 )
			pSkill->setPosition(ccp(size.width-(300*UIscaleFactor),55*UIscaleFactor));
		else if( i == 1 )
			pSkill->setPosition(ccp(size.width-(177*UIscaleFactor),55*UIscaleFactor));
		else
			pSkill->setPosition(ccp(size.width-(57*UIscaleFactor),55*UIscaleFactor));

		this->addChild(pSkill,SKILLSBUTTON);
	}

	//====================== GAME OVER ====================
	isGameOver = false;

    //======================= COMBO =======================
    comboCounter = 0;

    //====================== SCORE ========================
    gameScore = 0;

    //======================== LEVEL TITLE =======================
	CCLabelTTF * font = CCLabelTTF::create("The Scientist Escape", "Font/CarterOne.ttf", 45*UIscaleFactor);
	font->setAnchorPoint(ccp(0,0));
	font->enableStroke(ccc3(0,0,0),2,true);
	font->setPosition(ccp(30*UIscaleFactor,10*UIscaleFactor));
	this->addChild(font);

    //==================== AI DIRECTOR =====================
    CCArray* pCatSpawnSetArray = myLevel->getSpawnScript()->getSpawnSet();
    myPlayerPerformance = new PlayerPerformance(myLevel->getLevelDuration());
    myAIDirector = new AIDirector(myLevel->getMinDifficulty(), myLevel->getMaxDifficulty(), pCatSpawnSetArray, myPlayerPerformance);

    GameModifier::getInstance().init(myCharacter, myCatsManager);

    //================ SOUND PRELOAD ===================
    SoundLoader::preloadSounds();
}

//=========================Update function======================
/*!
 * @function: update
 * @brief: Cocos2d-x default library for update. Update function is called once every loop
 */
void GameManager::update(float dt)
{
	//If game is paused or has ended, we do not need to check for any logic
	if( isPaused || isGameOver )
		return;

	//================ AI DIRECTOR ===================
	CCLog("going to update AI Director");
	myPlayerPerformance->update(dt);
	myAIDirector->update(dt);
	CCLog("updated AI Director");
	//============= CHARACTER =================
	CCLog("going to update Character");
	myCharacter->update(dt);
	//Check if character health matches the UI health bar
	ReduceHealthUI(myCharacter->getHealth());
	//When out of health, end the game
	if( myCharacter->getHealth() <= 0 && !isGameOver )
	{
		endGame(false);
	}

	//============= CAT MANAGER =================
	CCLog("going to update CatsManager");
	myCatsManager->update(dt);
	CCLog("updated Character");
	//============= MAP =====================
	CCLog("going to update Map");
	myMap->update(myCharacter->getXSpeed(dt));
	CCLog("updated Map");
	//========== COMBO ==========
	if( comboOn && comboCounter > 0 )
	{
		comboTimer += dt;
		//If there are no new swipes in with 0.2 seconds of the last hit,
		//end the combo and damage all tracked cats
		if( comboTimer > 0.2 )
		{
			//Add charge points
			//3-4 = 1 point, 5 = 2 points, 6 & more = 3points
			int pointstoadd = comboCounter;
			if( comboCounter > 5 )
				pointstoadd = 3;
			else if( pointstoadd < 2 )
				pointstoadd = 0;
			else if( comboCounter == 5 )
				pointstoadd = 2;
			else
				pointstoadd = 1;
			adjustChargePoint(pointstoadd);

			comboOn = false;
			comboTimer = 0;
			comboCounter = 0;

			gameScore += myCatsManager->damageAllSwipedCats();
		}
	}

    //================Skills================
    for( int i = 0 ; i < mySkills->count() ; i++ )
    {
    	BaseSkill* skill = dynamic_cast<BaseSkill*>(mySkills->objectAtIndex(i));
    	skill->update(dt,myCatsManager,chargePoints);
    }
}

//===================================================Touches methods========================================
/*!
 * @function: ccTouchesBegan
 * @brief: Cocos2d-x default library for touches began, this function is called for every touch that touch the device's screen
 */
void GameManager::ccTouchesBegan(CCSet* touches, CCEvent* event)
{
	//endGame(false); //temp

	//If game is paused or has ended, we do not need to check for any logic
	if( isPaused || isGameOver )
		return;

	CCTouch* touch = (CCTouch*)(touches->anyObject());
	CCPoint location = touch->getLocationInView();
	location = CCDirector::sharedDirector()->convertToGL(location);

    for (CCSetIterator it = touches->begin(); it != touches->end(); it++) {
        CCTouch *touch = (CCTouch *)*it;
		CCBlade *blade = CCBlade::create("Game/streak.png", 4, 50);
        _map[touch] = blade;
		this->addChild(blade,SWIPEEFFECT);

        blade->setColor(ccc3(255,255,255));
        blade->setOpacity(100);
        blade->setDrainInterval(1.0/80);

        CCPoint point = convertTouchToNodeSpace(touch);
		blade->push(point);
	}

    //Skills
    for( int i = 0 ; i < mySkills->count() ; i++ )
    {
    	BaseSkill* skill = dynamic_cast<BaseSkill*>(mySkills->objectAtIndex(i));
    	//Check for skill touch, if there is skill touch, we do not want to check for touch with cats
    	if( skill->touchesBegan(location, this) )
    		return;
    }

    if( comboOn )
    {
		comboCounter = 0;
		myCatsManager->damageAllSwipedCats();
    }

    //Check collision and update the combo if necessary
	comboCounter = 0;
    int numberofhits = myCatsManager->checkCatTouchCollision(location);
    comboCounter += numberofhits;

	if( !comboOn )
	{
		comboOn = true;
		comboTimer = 0;
	}
}

/*!
 * @function: ccTouchesMoved
 * @brief: Cocos2d-x default library for touches moved, this function is called for every touch that moved on the device's screen
 */
void GameManager::ccTouchesMoved(CCSet* touches, CCEvent* event)
{
	//If game is paused or has ended, we do not need to check for any logic
	if( isPaused || isGameOver )
		return;

	CCTouch* touch = (CCTouch*)(touches->anyObject());
	CCPoint location = touch->getLocationInView();
	location = CCDirector::sharedDirector()->convertToGL(location);

    //Skills
    for( int i = 0 ; i < mySkills->count() ; i++ )
    {
    	BaseSkill* skill = dynamic_cast<BaseSkill*>(mySkills->objectAtIndex(i));
    	skill->touchesMoved(location);
    }

    //Check collision
	if( comboOn )
	{
	    for (CCSetIterator it = touches->begin(); it != touches->end(); it++) {
	        CCTouch *touch = (CCTouch *)*it;
	        if (_map.find(touch) == _map.end()) continue;

	        CCBlade *blade = _map[touch];
	        CCPoint point = convertTouchToNodeSpace(touch);
	        point = ccpAdd(ccpMult(point, 0.5f), ccpMult(touch->getPreviousLocation(), 0.5f));
			blade->push(point);
	    }

		int numberofhits = myCatsManager->checkCatTouchCollision(location);

		//comboOn = true;
		if( numberofhits > 0 )
		{
			comboTimer = 0;
			comboCounter += numberofhits;
		}
	}
}

/*!
 * @function: ccTouchesEnded
 * @brief: Cocos2d-x default library for touches ended, this function is called for every touch that is lifted off the screen
 */
void GameManager::ccTouchesEnded(CCSet* touches, CCEvent* event)
{
	//If game is paused or has ended, we do not need to check for any logic
	if( isPaused || isGameOver )
		return;

	CCTouch* touch = (CCTouch*)(touches->anyObject());
	CCPoint location = touch->getLocationInView();
	location = CCDirector::sharedDirector()->convertToGL(location);

    for (CCSetIterator it = touches->begin(); it != touches->end(); it++) {
        CCTouch *touch = (CCTouch *)*it;
        if (_map.find(touch) == _map.end()) continue;

        CCBlade *blade = _map[touch];
        blade->autoCleanup();
        _map.erase(touch);
    }

    if( comboOn && comboCounter == 0 )
    {
    	comboOn = false;
    }
}

/*
 * @function: didAccelerate
 * @brief: Cocos2d-x default library for accelerometer
 */
void GameManager::didAccelerate(cocos2d::CCAcceleration* pAccelerationValue)
{
	//Skills, only need to apply for earthquake skill
	for( int i = 0 ; i < mySkills->count() ; i++ )
	{
		BaseSkill* skill = dynamic_cast<BaseSkill*>(mySkills->objectAtIndex(i));
		if( skill->returnSkillType() == SKILL_EARTHQUAKE )
			((SkillEarthquake*)skill)->didAccelerate(pAccelerationValue, myCatsManager);
	}
}

//==================== UI ============================
/*!
 * @function: ReduceHealthUI
 * @paramater: health to be updated. Retrieved from character
 * @brief: Adjust the health UI. Each health can only be decreased by 1 each time it is called
 * @result: Health UI is replaced with a empty health UI
 */
void GameManager::ReduceHealthUI(int health)
{
	//It has to be more than 1 health remaining if not it should not enter
	if( health < myHealthUI->count() && myHealthUI->count() > 0 )
	{
		CCSprite *health = (CCSprite*)myHealthUI->objectAtIndex(myHealthUI->count()-1);

		CCSprite *losehealthsprite = CCSprite::create("Game/UI/[UI] HP Empty.png");
		losehealthsprite->setScale(health->getScale());
		losehealthsprite->setPosition(health->getPosition());

		this->removeChild(health);
		this->addChild(losehealthsprite,HEALTHSPRITE);

		myHealthUI->removeLastObject(true);
		myPlayerPerformance->reduceDifficulty();
	}
}

/*
 * @function: adjustChargePoint
 * @brief: adjust the charge point based on the amount, amount can be either positive(gain) or negative(loss)
 * @param amount: amount to reflect
 * @result: Adjust the charge point according to the amount
 * @return true: true if amount is valid and can be reflected, else false
 */
bool GameManager::adjustChargePoint(int amount)
{
	//If negative amount or there is insufficent to deduct, exit
	if( amount < 0 && (chargePoints+amount) < 0 )
		return false;

	chargePoints += amount;

	//Capped charge points at 10
	if( chargePoints > 10 )
		chargePoints = 10;

	adjustChargePointsUI(amount);

    //Skills, check if there is sufficient charge points to enable the skills
    for( int i = 0 ; i < mySkills->count() ; i++ )
    {
    	BaseSkill* skill = dynamic_cast<BaseSkill*>(mySkills->objectAtIndex(i));
    	skill->checkToEnableSkillButton(chargePoints);
    }

    return true;
}
/*!
 * @function: AdjustChargePointsUI
 * @brief: Adjust the charge points UI based on the adjustment amount, it can go both right (charing points) or left (deducting charge points) direction
 * @param: amount: int
 * 		   The amount to adjust. Charge bar has a capacity of 10. However amount can be of any int value
 * @result: charge point UI is reflected correctly
 */
void GameManager::adjustChargePointsUI(int amount)
{
	CCSize size = CCDirector::sharedDirector()->getWinSize();
	float UIscaleFactor = myMap->getScaleFactor();

	//Make sure is within limit
	if( amount >= -10 && amount <= 10 )
	{
		//If positive amount, we have to increase the charge bar
		if( amount > 0 )
		{
			while( amount > 0 )
			{
				CCSprite * chargepointUI;

				//Use left image
				if( mySkillChargeUI->count() == 0 )
				{
					chargepointUI = CCSprite::create("Game/UI/[UI] Skill Bar - Fill Left.png");
					chargepointUI->setPosition(ccp(size.width - (605*UIscaleFactor) ,size.height/2 - (277*UIscaleFactor)));
				}
				//Use right image
				else if( mySkillChargeUI->count() == 9 )
				{
					chargepointUI = CCSprite::create("Game/UI/[UI] Skill Bar - Fill Right.png");
					chargepointUI->setPosition(ccp(size.width - (605*UIscaleFactor) + (225*UIscaleFactor) ,size.height/2 - (277*UIscaleFactor)));
				}
				else if( mySkillChargeUI->count() < 9 )
				{
					chargepointUI = CCSprite::create("Game/UI/[UI] Skill Bar - Fill Mid.png");
					chargepointUI->setPosition(ccp(size.width - (605*UIscaleFactor) + (mySkillChargeUI->count()*25*UIscaleFactor) ,size.height/2 - (277*UIscaleFactor)));
				}
				//Else the charge bar is already full, can safely break
				else
				{
					break;
				}

				chargepointUI->setScale(UIscaleFactor);
				this->addChild(chargepointUI,SKILLBARSPRITE+1);
				mySkillChargeUI->addObject(chargepointUI);

				amount -= 1;
			}
		}
		//If negative amount, it means we have to reduce the charge bar
		else if( amount < 0 )
		{
			while( amount < 0 )
			{
				if( mySkillChargeUI->count() > 0 )
				{
					this->removeChild((CCSprite*)mySkillChargeUI->lastObject());
					mySkillChargeUI->removeLastObject(true);
				}

				amount += 1;
			}
		}
	}
}

//===================UI Buttons===============
/*!
 * @function: pauseButtonPressed
 * @brief: create a in game pause menu when pause button is pressed
 */
void GameManager::pauseButtonPressed()
{
	if( !isPaused && !isGameOver )
	{
		isPaused = true;

		this->getChildByTag(tagoffset+PROGRESSIONINDICATORSPRITE)->pauseSchedulerAndActions();

		CCSize size = CCDirector::sharedDirector()->getWinSize();
		float UIscaleFactor = myMap->getScaleFactor();

		CCLayerColor *bg = CCLayerColor::create(ccc4(50,50,50,220),size.width,size.height);
		bg->setTag(tagoffset+PAUSEBG);
		this->addChild(bg,PAUSEBG);

		//Pause title sprite
		CCSprite *pausetitleSprite = CCSprite::create("Game/Pause/[Text] Pause.png");
		pausetitleSprite->setScale(UIscaleFactor);
		pausetitleSprite->setPosition(ccp(size.width/2,size.height/2 + (200*UIscaleFactor)));
		pausetitleSprite->setTag(tagoffset+PAUSETITLE);
		this->addChild(pausetitleSprite,PAUSETITLE);

		//Resume button
		CCSprite * resumeButtonSprite = CCSprite::create("Game/Pause/[Button Large] Play - Normal.png");
		CCSprite * resumeButtonSpritePressed = CCSprite::create("Game/Pause/[Button Large] Play - Pressed.png");
		CCMenuItemSprite* resumeButton = CCMenuItemSprite::create(resumeButtonSprite,resumeButtonSpritePressed,this,menu_selector(GameManager::resumeButtonPressedPaused));
		resumeButton->setScale(UIscaleFactor);
		resumeButton->setPosition(ccp(size.width/2 - (250*UIscaleFactor),size.height/2 + (50*UIscaleFactor)));

		//Restart button
		CCSprite * restartButtonSprite = CCSprite::create("Game/Pause/[Button Large] Reload - Normal.png");
		CCSprite * restartButtonSpritePressed = CCSprite::create("Game/Pause/[Button Large] Reload - Pressed.png");
		CCMenuItemSprite* restartButton = CCMenuItemSprite::create(restartButtonSprite,restartButtonSpritePressed,this,menu_selector(GameManager::restartButtonPressedPaused));
		restartButton->setScale(UIscaleFactor);
		restartButton->setPosition(ccp(size.width/2,size.height/2 + (50*UIscaleFactor)));

		//Exit button
		CCSprite * exitButtonSprite = CCSprite::create("Game/Pause/[Button Large] Exit - Normal.png");
		CCSprite * exitButtonSpritePressed = CCSprite::create("Game/Pause/[Button Large] Exit - Pressed.png");
		CCMenuItemSprite* exitButton = CCMenuItemSprite::create(exitButtonSprite,exitButtonSpritePressed,this,menu_selector(GameManager::exitButtonPressedPaused));
		exitButton->setScale(UIscaleFactor);
		exitButton->setPosition(ccp(size.width/2 + (250*UIscaleFactor),size.height/2 + (50*UIscaleFactor) ));

		//SFX button
		CCSprite * soundButtonSprite;
		CCSprite * soundButtonSpritePressed;
		//If SFX is enabled by default
		if( !SoundLoader::getIsSoundEffect() )
		{
			soundButtonSprite = CCSprite::create("Game/Pause/[Button] SFX - Normal.png");
			soundButtonSpritePressed = CCSprite::create("Game/Pause/[Button] SFX - Pressed.png");
		}
		//Else display another set of button that shows SFX is muted
		else
		{
			soundButtonSprite = CCSprite::create("Game/Pause/[Button] SFX - Mute.png");
			soundButtonSpritePressed = CCSprite::create("Game/Pause/[Button] SFX - Mute Pressed.png");
		}

		CCMenuItemSprite* soundButton = CCMenuItemSprite::create(soundButtonSprite,soundButtonSpritePressed,this,menu_selector(GameManager::soundButtonPressedPaused));
		soundButton->setScale(UIscaleFactor);
		soundButton->setTag(tagoffset+PAUSESFX);
		soundButton->setPosition(ccp(size.width/2 - (100*UIscaleFactor),size.height/2 - (120*UIscaleFactor)));

		//Music button
		CCSprite * musicButtonSprite;
		CCSprite * musicButtonSpritePressed;
		//If BGM is enabled by default
		if( !SoundLoader::getIsBackgroundMusic() )
		{
			musicButtonSprite = CCSprite::create("Game/Pause/[Button] Music - Normal.png");
			musicButtonSpritePressed = CCSprite::create("Game/Pause/[Button] Music - Pressed.png");
		}
		//Else display another set of button that show BGM is muted
		else
		{
			musicButtonSprite = CCSprite::create("Game/Pause/[Button] Music - Mute.png");
			musicButtonSpritePressed = CCSprite::create("Game/Pause/[Button] Music - Mute Pressed.png");
		}
		CCMenuItemSprite* musicButton = CCMenuItemSprite::create(musicButtonSprite,musicButtonSpritePressed,this,menu_selector(GameManager::musicButtonPressedPaused));
		musicButton->setScale(UIscaleFactor);
		musicButton->setTag(tagoffset+PAUSEMUSIC);
		musicButton->setPosition(ccp(size.width/2 + (100*UIscaleFactor),size.height/2 - (120*UIscaleFactor)));

		CCMenu* pausemenu = CCMenu::create(resumeButton,restartButton,exitButton,soundButton,musicButton, NULL);
		pausemenu->setPosition(0,0);
		pausemenu->setTag(tagoffset+PAUSEMENU);
		this->addChild(pausemenu,PAUSEMENU);

		this->pauseSchedulerAndActions();
	}
}
/*!
 * @function: resumeButtonPressedPaused
 * @brief: Resume the game when resume button is pressed from PAUSE menu
 */
void GameManager::resumeButtonPressedPaused()
{
	this->removeChildByTag(tagoffset+PAUSEBG);
	this->removeChildByTag(tagoffset+PAUSETITLE);
	this->removeChildByTag(tagoffset+PAUSEMENU);

	this->getChildByTag(tagoffset+PROGRESSIONINDICATORSPRITE)->resumeSchedulerAndActions();
	this->resumeSchedulerAndActions();

	isPaused = false;
}
/*!
 * @function: restartButtonPressedPaused
 * @brief: restart the game when resume button is pressed from PAUSE menu. A brand new level will be reloaded
 */
void GameManager::restartButtonPressedPaused()
{
	myFlowController->switchScreenTo(SCREEN_SKILLSELECT);
}
/*!
 * @function: exitButtonPressedPaused
 * @brief: Exit the game when exit button is pressed from PAUSE menu. Game should return to main menu
 */
void GameManager::exitButtonPressedPaused()
{
	myFlowController->switchScreenTo(SCREEN_MAIN);
}
/*!
 * @function: soundButtonPressedPaused
 * @brief: Toogle the sound when sound button is pressed from PAUSE menu
 */
void GameManager::soundButtonPressedPaused()
{
	CCMenu* menu = (CCMenu*)this->getChildByTag(tagoffset+PAUSEMENU);
	CCMenuItemSprite *sfxButton = (CCMenuItemSprite*)menu->getChildByTag(tagoffset+PAUSESFX);
	if( !SoundLoader::getIsSoundEffect() )
	{
		sfxButton->setNormalImage(CCSprite::create("Game/Pause/[Button] SFX - Mute.png"));
		sfxButton->setSelectedImage(CCSprite::create("Game/Pause/[Button] SFX - Mute Pressed.png"));
	}
	else
	{
		sfxButton->setNormalImage(CCSprite::create("Game/Pause/[Button] SFX - Normal.png"));
		sfxButton->setSelectedImage(CCSprite::create("Game/Pause/[Button] SFX - Pressed.png"));
	}

	SoundLoader::toggleSoundEffect();
}
/*!
 * @function: musicButtonPressedPaused
 * @brief: Toogle the music when music button is pressed from PAUSE menu
 */
void GameManager::musicButtonPressedPaused()
{
	CCMenu* menu = (CCMenu*)this->getChildByTag(tagoffset+PAUSEMENU);
	CCMenuItemSprite *sfxButton = (CCMenuItemSprite*)menu->getChildByTag(tagoffset+PAUSEMUSIC);
	if( !SoundLoader::getIsBackgroundMusic() )
	{
		sfxButton->setNormalImage(CCSprite::create("Game/Pause/[Button] Music - Mute.png"));
		sfxButton->setSelectedImage(CCSprite::create("Game/Pause/[Button] Music - Mute Pressed.png"));
	}
	else
	{
		sfxButton->setNormalImage(CCSprite::create("Game/Pause/[Button] Music - Normal.png"));
		sfxButton->setSelectedImage(CCSprite::create("Game/Pause/[Button] Music - Pressed.png"));
	}

	SoundLoader::toggleBackgroundMusic();
}
/*!
 * @function: exitButtonPressedPaused
 * @brief: Exit the game when exit button is pressed from PAUSE menu. Game should return to main menu
 */
void GameManager::forwardButtonPressedGameOver()
{
	myFlowController->switchScreenTo(SCREEN_LEVELSELECT);
}
/*!
 * @function: keyBackClicked
 * @brief: Pause the game when the device's return button key is pressed.
 */
void GameManager::keyBackClicked()
{
	pauseButtonPressed();
}

void GameManager::winGame()
{
	endGame(true);
}
/*!
 * @function: endGame
 * @brief: end game function.
 * @param isWin: true if user win game, else false
 * @result: display win screen if isWin, else display lose screen
 */
void GameManager::endGame(bool isWin)
{
	//Set gameover to true to disable update and touches methods
	isGameOver = true;

	//Display game over scene
	CCSize size = CCDirector::sharedDirector()->getWinSize();

	//Stop the progression bar action so it does continue to move
	this->getChildByTag(tagoffset+PROGRESSIONINDICATORSPRITE)->stopAllActions();

	CCSprite *gameoverSprite;
	CCSprite *stars;

	//Win game situation. We need to display both the win game screen as well as display the stars
	if( isWin )
	{
		SoundLoader::playSound(LEVEL_COMPLETE);

		gameoverSprite = CCSprite::create("Game/UI/[UI] Level Clear.png");

		gameScore += (150*myCharacter->getHealth());
		int offset = 102;
		int rectlength = 102;

		// two star
		if( gameScore < 1000 && gameScore >= 300 )
		{
			rectlength = 204;
			offset = 51;
		}
		// three star
		else if( gameScore >= 1000 )
		{
			rectlength = 306;
			offset = 0;
		}
		//else it will be default to one star

		stars = CCSprite::create("Game/UI/[UI] Level Clear - Star.png",CCRectMake(0,0,rectlength,105));
		stars->setScale(myMap->getScaleFactor());
		//stars->setAnchorPoint(ccp(stars->boundingBox().))
		stars->setPosition(ccp(size.width/2-(offset*myMap->getScaleFactor()),size.height/2+(48*myMap->getScaleFactor())));
		this->addChild(stars,tagoffset+GAMEOVERBUTTONS);
	}
	//Lose game situation
	else
	{
		gameoverSprite = CCSprite::create("Game/UI/[UI] Level Fail.png");
	}
	gameoverSprite->setScale(myMap->getScaleFactor());
	gameoverSprite->setPosition(ccp(size.width/2,size.height/2));
	this->addChild(gameoverSprite,tagoffset+GAMEOVER);

	//Display score
	CCString *scorestring = CCString::createWithFormat("%d",gameScore);
	CCLabelTTF * font = CCLabelTTF::create(scorestring->getCString(), "Font/CarterOne.ttf", 30*myMap->getScaleFactor());
	font->setAnchorPoint(ccp(0,0));
	font->enableStroke(ccc3(0,0,0),2,true);
	font->setPosition(ccp(size.width/2+(30*myMap->getScaleFactor()),size.height/2 - (75*myMap->getScaleFactor())));
	this->addChild(font,tagoffset+GAMEOVERBUTTONS);

	//If player won the game, save the results out
	if( isWin )
		PlayerData::saveLevelResults(PlayerData::getSelectedLevel(),gameScore,true);
	else
		PlayerData::saveLevelResults(PlayerData::getSelectedLevel(),gameScore,false);

	//Display high score
	int currenthighscore = PlayerData::getLevelScore(PlayerData::getSelectedLevel());
	CCString *highscorestring = CCString::createWithFormat("%d",currenthighscore);
	CCLabelTTF * font2 = CCLabelTTF::create(highscorestring->getCString(), "Font/CarterOne.ttf", 30*myMap->getScaleFactor());
	font2->setAnchorPoint(ccp(0,0));
	font2->enableStroke(ccc3(0,0,0),2,true);
	font2->setPosition(ccp(size.width/2+(60*myMap->getScaleFactor()),size.height/2 - (122*myMap->getScaleFactor())));
	this->addChild(font2,tagoffset+GAMEOVERBUTTONS);

	//Restart button
	CCSprite * restartButtonSprite = CCSprite::create("Game/Pause/[Button Large] Reload - Normal.png");
	CCSprite * restartButtonSpritePressed = CCSprite::create("Game/Pause/[Button Large] Reload - Pressed.png");
	CCMenuItemSprite* restartButton = CCMenuItemSprite::create(restartButtonSprite,restartButtonSpritePressed,this,menu_selector(GameManager::restartButtonPressedPaused));
	restartButton->setScale(myMap->getScaleFactor()*0.7);
	restartButton->setPosition(ccp(size.width/2-(100*myMap->getScaleFactor()),size.height/2 - (180*myMap->getScaleFactor())));

	//Continue button
	CCSprite * continueButtonSprite = CCSprite::create("Game/UI/[Button] Forward - Normal.png");
	CCSprite * continueButtonSpritePressed = CCSprite::create("Game/UI/[Button] Forward - Pressed.png");
	CCMenuItemSprite* continueButton = CCMenuItemSprite::create(continueButtonSprite,continueButtonSpritePressed,this,menu_selector(GameManager::forwardButtonPressedGameOver));
	continueButton->setScale(myMap->getScaleFactor());
	continueButton->setPosition(ccp(size.width/2 + (100*myMap->getScaleFactor()),size.height/2 - (180*myMap->getScaleFactor()) ));

	CCMenu* pausemenu = CCMenu::create(restartButton,continueButton, NULL);
	pausemenu->setPosition(0,0);
	this->addChild(pausemenu,tagoffset+GAMEOVERBUTTONS);
}

/**
 * @brief: return the change points of the player
 * @return: charge points of the player
 */
int GameManager::getChargePoints()
{
	return chargePoints;
}
